package classDemo;
/**
 * 类加载机制
 * 
 * https://www.jianshu.com/p/8c8d6cba1f8e
 * 
 * 1、执行TestSingleton第一句的时候，因为我们没有对Singleton类进行加载和连接，
 *   所以我们首先需要对它进行加载和连接操作。在连接阶-准备阶段，我们要讲给静态变量赋予默认初始值。
 *   singleton2 =null
 *   counter1 =0
 *   counter2 =0
 *   
 * 2、 加载和连接完毕之后，我们再进行初始化工作。初始化工作是从上往下依次执行的，
 *   注意这个时候还没有调用Singleton.getSingleton2();
 *   首先 singleton2 = new Singleton2();这样会执行构造方法内部逻辑，进行++；
 *   此时counter1=1，counter2 =1 ；
 *   接下来再看第二个静态属性，我们并没有对它进行初始化，所以它就没办法进行初始化工作了；
 *   第三个属性counter2我们初始化为0 ,而在初始化之前counter2=1，
 *   执行完counter2=0之后counter2=0了；
 *   
 * 3、初始化完毕之后我们就要调用静态方法Singleton.getSingleton2();
 *   我们知道返回的singleton已经初始化了。
 *   那么输出的内容也就理所当然的是1和0了。
 *   这样一步一步去理解程序执行过程是不是让你清晰的认识了java虚拟机执行程序的逻辑呢。
 *   
 *
 * @author zybw-kf01
 *
 */
public class ClassLoad6_NumTest {
	public static void main(String args[]) {
		Singleton6 singleton6 = Singleton6.getSingleton6();
		System.out.println("counter1=" + singleton6.counter1);
		System.out.println("counter2=" + singleton6.counter2);
	}

}


class Singleton6 {
	private static Singleton6 singleton6 = new Singleton6();
	public static int counter1;
	public static int counter2 = 0;
	/*那么我们接下来改变一下代码顺序，将
	 public static int counter1;
	 public static int counter2 = 0;
	 private static Singleton2 singleton2 = new Singleton2();
	 又会输出什么呢？为什么这样输出呢？
	 这个问题留给大家去思考，主要还是理解为什么这样输出才是最重要的。
	*/ 
	private Singleton6() {
		System.out.println("constructor");
		counter1++;
		counter2++;
	}

	static class SingleHolder{
		 static Singleton6 instance = new Singleton6();
		 static {
			 System.out.println("inner class static block");
		 }
	}

	public static Singleton6 getSingleton6() {
		return singleton6;
	}

}
